from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
import numpy as np

# 加载数据
iris = load_iris()
X, y =iris.data , iris.target

# 数据集信息
print("特征名称:", iris.feature_names)
print("类别名称:", iris.target_names)
print("数据形状:", X.shape)
print("前5个标签:", y[:5])

# 手动划分数据集（分层抽样）
np.random.seed(42)
test_size = 0.25
train_idx, test_idx = [], []
for cls in np.unique(y):
    idx = np.where(y == cls)[0]
    np.random.shuffle(idx)
    split = int(len(idx) * (1-test_size))
    train_idx.extend(idx[:split])
    test_idx.extend(idx[split:])
X_train, X_test = X[train_idx], X[test_idx]
y_train, y_test = y[train_idx], y[test_idx]

# KNN参数
k = 5

# 手动实现KNN预测
def knn_predict(x):
    # 计算距离并获取最近k个样本的标签
    distances = np.sqrt(((X_train - x) **2).sum(axis=1))
    nearest_labels = y_train[np.argsort(distances)[:k]]
    # 多数投票
    return np.bincount(nearest_labels).argmax()

# 批量预测
y_pred = [knn_predict(x) for x in X_test]

# 评估
print(f"\n准确率: {accuracy_score(y_test, y_pred):.2%}")

# 预测新样本
new_flower = [[5.1, 3.5, 1.4, 0.2]]
pred = knn_predict(new_flower[0])
print(f"预测类型: {iris.target_names[pred]}")
